package sender;

import common.Packet;
import java.util.ArrayList;
import java.util.Random;

/**
 * The Filter class simulates an unreliable channel by duplicating, corrupting,
 * or dropping a packet within a certain probability.
 * @author Joe
 */
public class Filter 
{
    private final static int DROP_PROBABILITY = 5;
    private final static int DUPLICATE_PROBABILITY = 10;
    private final static int CORRUPT_PROBABILITY = 5;
    /** "Scrambles" a packet.
     * @param packet The packet to be scrambled.
     * @return A list of packets, representing the results of the scramble.  If
     * a duplication occurred, the list will contain two packets, either of 
     * which may be corrupted.  If a drop occurred, the list will be empty.
     */
    public static ArrayList<Packet> scramble(Packet original, Results result)
    {
        Packet packet = new Packet(original.getRaw());
        ArrayList<Packet> packets = new ArrayList();
        // Evaluate the probability for a drop
        if (!willHappen(DROP_PROBABILITY))
        {
            packets.add(packet);
        }
        // Evaluate the probability for a duplicate
        if (willHappen(DUPLICATE_PROBABILITY))
        {
            packets.add(new Packet(packet));
            result.duplicated++;
        }
        // Evaluate the probability for corruption
        for (Packet p : packets)
        {
            if (willHappen(CORRUPT_PROBABILITY))
            {
                // TODO: rewrite one of the packet fields with dummy data
                p.checksum = 0;
                result.corrupted++;
            }
        }
        if (packets.isEmpty())
        {
            result.dropped++;
        }
        
        return packets;
    }
    private static boolean willHappen(int probability)
    {
        return new Random().nextInt(100) < probability - 1;
    }
}
